package org.noote.libs.camera.helper;

import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.util.Log;
import android.view.Surface;

public class Helper_Camera {
	private static final String TAG = "Helper_Camera";
	
	static public boolean checkCameraHardware(Context context) {
	    if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
	    	&& !context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT))
	    {
	    	Log.e(TAG, "No camera on system");
	    	return false;
	    }
	    if(Camera.getNumberOfCameras()==0){
	    	Log.e(TAG, "Zero camera in system ?");
	    	return false;
	    }
	    
	    return true;
	}
	
	public static int getCamera(){
	   int cid = getDefaultCamera();
	    if(cid==-1)
	    	cid=getBackCamera();
	    if(cid==-1)
	    	cid=getFrontCamera();
	    return cid; // returns -1 if camera is unavailable
	}
	
	public static int getDefaultCamera(){
		int cameraID = findCamera(-1, -1);
		if(cameraID>-1)
			return cameraID;

	    return -1;
	}
	
	public static int getFrontCamera(){
		int cameraID = findCamera(CameraInfo.CAMERA_FACING_FRONT, -1);
		if(cameraID>-1)
			return cameraID;

	    return -1;
	}
	
	public static int getBackCamera(){
		int cameraID = findCamera(CameraInfo.CAMERA_FACING_BACK, -1);
		if(cameraID>-1)
			return cameraID;

	    return -1;
	}
	
	public static int findCamera(int facing, int orientation){
		
		int numberOfCameras = Camera.getNumberOfCameras();
		for(int i=0; i<numberOfCameras; i++)
		{
			CameraInfo ci = new CameraInfo();
			Camera.getCameraInfo(i, ci);
			if(orientation == -1 && facing == -1)
				return i;
			else if(orientation == -1 && facing != -1 && ci.facing == facing)
				return i;
			else if(facing == -1 && orientation != -1 && ci.orientation == orientation)
				return i;
			else if(facing != -1 && ci.facing == facing
					&& orientation != -1 && ci.orientation == orientation)
				return i;
		}

	    return -1;
	}
	
	public static Size getOptimalSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.2;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;

        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        int targetHeight = h;

        // Try to find an size match aspect ratio and size
        for (Size size : sizes) {
            Log.d(TAG, "Checking size " + size.width + "w " + size.height
                    + "h");
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - targetHeight) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - targetHeight);
            }
        }

        // Cannot find the one match the aspect ratio, ignore the
        // requirement
        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
        }
        return optimalSize;
    }
	
	public static int findCameraDisplayOrientation(Activity activity, int cameraId)
	{
	     android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
	     android.hardware.Camera.getCameraInfo(cameraId, info);
	     int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
	     int degrees = 0;
	     switch (rotation) {
	         case Surface.ROTATION_0: degrees = 0; break;
	         case Surface.ROTATION_90: degrees = 90; break;
	         case Surface.ROTATION_180: degrees = 180; break;
	         case Surface.ROTATION_270: degrees = 270; break;
	     }
	     degrees+=90;

	     int result;
	     if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
	         result = (info.orientation + degrees) % 360;
	         result = (360 - result) % 360;  // compensate the mirror
	     } else {  // back-facing
	         result = (info.orientation - degrees + 360) % 360;
	     }
	     
	     return result;
	 }
}
